package com.xnx3.kefu.core.pluginManage.interfaces.manage;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Component;
import com.xnx3.ScanClassUtil;
import com.xnx3.j2ee.util.ConsoleUtil;
import com.xnx3.j2ee.vo.BaseVO;
import com.xnx3.kefu.core.bean.ChatUserBean;
import com.xnx3.kefu.core.pluginManage.interfaces.MessageInterface;
import com.xnx3.kefu.core.vo.MessageReceiveVO;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;

/**
 * 消息相关
 * @author 管雷鸣
 *
 */
@Component(value="PluginManageForKefuMessage")
public class MessagePluginManage {
	//这里开启项目时，便将有关此的插件加入此处
	public static List<Class<?>> classList;
	static{
		classList = new ArrayList<Class<?>>();
		
		try {
			List<Class<?>> allClassList = ScanClassUtil.getClasses("com.xnx3");
			classList = ScanClassUtil.searchByInterfaceName(allClassList, "com.xnx3.kefu.core.pluginManage.interfaces.MessageInterface");
			for (int i = 0; i < classList.size(); i++) {
				ConsoleUtil.info("装载 Kefu MessageInterface 插件："+classList.get(i).getName());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 离线消息处理，说明参考 {@link MessageInterface#offlineMessage(Channel, MessageReceiveVO)}
	 */
	public static void offlineMessage(Channel channel, MessageReceiveVO message){
		for (int i = 0; i < classList.size(); i++) {
			try {
				Class<?> c = classList.get(i);
				Object invoke = null;
				invoke = c.newInstance();
				//运用newInstance()来生成这个新获取方法的实例  
				Method m = c.getMethod("offlineMessage",new Class[]{Channel.class, MessageReceiveVO.class});	//获取要调用方法
				m.invoke(invoke, new Object[]{channel, message});
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	

	/**
	 * 用户上线，socket建立连接触发。
	 */
	public static void online(Channel channel){
		for (int i = 0; i < classList.size(); i++) {
			try {
				Class<?> c = classList.get(i);
				Object invoke = null;
				invoke = c.newInstance();
				//运用newInstance()来生成这个新获取方法的实例  
				Method m = c.getMethod("online",new Class[]{Channel.class});	//获取要调用方法
				m.invoke(invoke, new Object[]{channel});
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 用户下线，socket断开连接触发。
	 */
	public static void offline(Channel channel){
		for (int i = 0; i < classList.size(); i++) {
			try {
				Class<?> c = classList.get(i);
				Object invoke = null;
				invoke = c.newInstance();
				//运用newInstance()来生成这个新获取方法的实例  
				Method m = c.getMethod("offline",new Class[]{Channel.class});	//获取要调用方法
				m.invoke(invoke, new Object[]{channel});
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	

	/**
	 * 当客户端发送正常消息进行交流时触发。这个已经抛除了打开链接、以及常见问题的自动匹配，触发这个的都是用户主动发送的消息
	 * @param channel 当前socket通道
	 * @param msg 客户端发送过来的消息对象
	 * @param 返回true，那么继续向后执行，如果返回false，就不再继续往下执行了 （nettyHandler中注解的后面的代码执行）
	 */
	public static boolean messageReceivedChat(Channel channel, MessageReceiveVO msg){
		for (int i = 0; i < classList.size(); i++) {
			try {
				Class<?> c = classList.get(i);
				Object invoke = null;
				invoke = c.newInstance();
				//运用newInstance()来生成这个新获取方法的实例  
				Method m = c.getMethod("messageReceivedChat",new Class[]{Channel.class, MessageReceiveVO.class});	//获取要调用方法
				Object o = m.invoke(invoke, new Object[]{channel, msg});
				if(o != null){
					boolean result = (boolean) o;
					if(result == false){
						//终止执行，直接返回false
						return false;
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		return true;
	}
	


	/**
	 * 当socket通道打开，获取回复语执行之前触发
	 * @param channel 上线用户当前的socket通道
	 * @param otherChatId 跟当前socket用户的对方的chatid，也就是当前要拉取的，自动回复的那个人的chatid，别人的chatid
	 */
	public static void autoReply(Channel channel, String otherChatId){
		for (int i = 0; i < classList.size(); i++) {
			try {
				Class<?> c = classList.get(i);
				Object invoke = null;
				invoke = c.newInstance();
				//运用newInstance()来生成这个新获取方法的实例  
				Method m = c.getMethod("autoReply",new Class[]{Channel.class, String.class});	//获取要调用方法
				m.invoke(invoke, new Object[]{channel, otherChatId});
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	
}
